﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using TomShane.Neoforce.Controls;

namespace SpaceInvade
{
    class FreeMode : GameState
    {
        public static String EnemyShipDirection = "Right";
        public static List<Ships.Ship> PlayerShips = new List<Ships.Ship>();
        public static List<Ships.Ship> EnemyShips = new List<Ships.Ship>();
        public static List<Star> starsList = new List<Star>();
        public List<Ships.Bullet> PlayerBullets = new List<Ships.Bullet>();
        public List<Ships.Bullet> EnemyBullets = new List<Ships.Bullet>();

        private ImageBox ibxGameScreen = null;
        private RenderTarget2D rndGameScreen = null;

        private Texture2D backgroundImage = null;
        Rectangle backSrc;
        Rectangle backDest1;
        Rectangle backDest2;

        SpriteBatch spriteBatch = null;

        public static Label lblDisposable = null;

        GameInfo GameInfo;

        public FreeMode(Manager manager, GameInfo GI) : base(manager)
        {
            Manager.GraphicsDevice.Clear(Color.White);
            rndGameScreen = Manager.CreateRenderTarget();

            spriteBatch = new SpriteBatch(Manager.GraphicsDevice);
            backSrc = new Rectangle(0, 0, Manager.Graphics.PreferredBackBufferWidth, Manager.Graphics.PreferredBackBufferHeight);
            backDest1 = new Rectangle(0, 0, Manager.Graphics.PreferredBackBufferWidth, Manager.Graphics.PreferredBackBufferHeight);
            backDest2 = new Rectangle(backDest1.X, backDest1.Y - backDest1.Height, backDest1.Width, backDest1.Height);

            GameInfo = GI;

            InitGUI();
        }
        // Detect User interaction with gui. If he choses a gamestate, exit the loop
        public override void Update()
        {
            //Create a star in background
            starsList.Add(new Star(Manager));

            // Code for handling ship movement and direction change
            bool ChangeDirection = false;
            foreach (Ships.Ship ship in EnemyShips)
            {
                bool TempChangeDirection;
                TempChangeDirection = ship.Move(Manager, EnemyShipDirection);
                if (TempChangeDirection && (ChangeDirection == false))
                    ChangeDirection = true;
            }
            foreach (Ships.Ship ship in PlayerShips)
            {
                ship.Move(Manager, EnemyShipDirection);
            }
            if (ChangeDirection == true)
            {
                if (EnemyShipDirection == "Right")
                    EnemyShipDirection = "Left";
                else
                    EnemyShipDirection = "Right";
            }
            foreach (Ships.Ship ship in PlayerShips)
            {
                // Allow each ship to shoot if appropriate. Ship will add it's bullet to the list.
                ship.ShootBullet(ref PlayerBullets);
            }

            foreach (Ships.Ship ship in EnemyShips)
            {
                // Allow each ship to shoot if appropriate. Ship will add it's bullet to the list.
                ship.ShootBullet(ref EnemyBullets);
            }
            foreach (Ships.Ship ship in EnemyShips)
            {
                for (int b = 0; b < PlayerBullets.Count; b++)
                {
                    if (ship.CheckCollision(PlayerBullets[b]))
                        PlayerBullets.RemoveAt(b);
                }
            }

            foreach (Ships.Ship ship in PlayerShips)
            {
                for (int b = 0; b < EnemyBullets.Count; b++)
                {
                    if (ship.CheckCollision(EnemyBullets[b]))
                        EnemyBullets.RemoveAt(b);
                }
            }
            // Check for dead ships and remove the object
            for (int i = PlayerShips.Count - 1; i >= 0; --i)
            {
                if (PlayerShips[i].IsDead())
                    PlayerShips.RemoveAt(i);
            }
            // Check for dead ships and remove the object
            for (int i = EnemyShips.Count - 1; i >= 0; --i)
            {
                if (EnemyShips[i].IsDead())
                    EnemyShips.RemoveAt(i);
            }

            //Check for stars outside range and update position
            for (int i = starsList.Count - 1; i >= 0; --i)
            {
                if (starsList[i].Update())
                    starsList.RemoveAt(i);
            }

            //Check for bullet out of bounds and update position
            for (int i = PlayerBullets.Count - 1; i >= 0; --i)
            {
                if (PlayerBullets[i].Update())
                    PlayerBullets.RemoveAt(i);
            }
            for (int i = EnemyBullets.Count - 1; i >= 0; --i)
            {
                if (EnemyBullets[i].Update())
                    EnemyBullets.RemoveAt(i);
            }
            base.Update();
        }
        //Draw Gui 
        public override void Draw()
        {
            if (rndGameScreen == null)
                return;

            Manager.GraphicsDevice.SetRenderTarget(rndGameScreen);
            Manager.GraphicsDevice.Clear(Color.Black);

            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            // spriteBatch.Draw(backgroundImage, backDest, backSrc, Color.White);
            DrawBackground();
            foreach (Star star in starsList)
            {
                star.Draw(spriteBatch);
            }
            foreach (Ships.Ship ship in PlayerShips)
            {
                ship.Draw(spriteBatch);
            }
            foreach (Ships.Ship ship in EnemyShips)
            {
                ship.Draw(spriteBatch);
            }
            foreach (Ships.Bullet bullet in PlayerBullets)
            {
                bullet.Draw(spriteBatch);
            }
            foreach (Ships.Bullet bullet in EnemyBullets)
            {
                bullet.Draw(spriteBatch);
            }
            spriteBatch.End();
            base.Draw();

            ibxGameScreen.Image = rndGameScreen;
            Manager.GraphicsDevice.SetRenderTarget(null);
        }
        // Draw moving background
        private void DrawBackground()
        {
            // If background1 falls off the bottom of the screen, reset it just above the screen
            if (backDest1.Y > backDest1.Height)
                backDest1.Y = backDest2.Y - backDest2.Height;
            // Slide background    
            backDest1.Y += 1;
            // If background1 falls off the bottom of the screen, reset it just above the screen
            if (backDest2.Y > backDest2.Height)
                backDest2.Y = backDest1.Y - backDest1.Height;
            // Slide background
            backDest2.Y += 1;
            // Draw each background
            spriteBatch.Draw(backgroundImage, backDest1, backSrc, Color.White);
            spriteBatch.Draw(backgroundImage, backDest2, backSrc, Color.White);
        }
        public override void InitializeCurrentLevel(int CurrentLevel)
        {
            //Set background image
            backgroundImage = Manager.Content.Load<Texture2D>(@"Images\starBack");

            //Import/Create Objects
            LevelReader.ImportXMLData("XML/Level" + CurrentLevel + ".xml", CurrentLevel, ref EnemyShips);

            // Create starfield
            for (int i = 0; i < 60; i++)
            {
                starsList.Add(new Star(Manager));
            }
            //Create player ships
            for (int x = 0; x < 4; x++)
            {
                if(GameInfo.lstPlayers[x].InUse == true)
                    PlayerShips.Add(new Ships.PlayerShip("Free", Manager,
                        320, 448, Color.MediumTurquoise, GameInfo.lstPlayers[0]));
            }

            //Audio
            Sound.PlaySong("music1");
        }
        private void InitGUI()
        {
            ibxGameScreen = new ImageBox(Manager);
            ibxGameScreen.Init();
            ibxGameScreen.Top = 0;
            ibxGameScreen.Left = 0;
            ibxGameScreen.Height = Manager.Graphics.PreferredBackBufferHeight;
            ibxGameScreen.Width = Manager.Graphics.PreferredBackBufferWidth;
            Manager.Add(ibxGameScreen);

            lblDisposable = new Label(Manager);
            lblDisposable.Init();
            lblDisposable.Parent = ibxGameScreen;
            lblDisposable.Top = 20;
            lblDisposable.Left = lblDisposable.Parent.Width - 30;
            lblDisposable.Text = Disposable.Count.ToString();
            lblDisposable.Width = 50;

        }
        public override void Dispose()
        {
            rndGameScreen.Dispose();
            ibxGameScreen.Dispose();
            starsList.Clear();
            base.Dispose();
        }
    }
}
